home *** CD-ROM | disk | FTP | other *** search
/ Clickx 96 / Clickx 96.iso / software / tools / tool / xbmc-10.1.exe / addons / webinterface.default / js / MediaLibrary.js < prev    next >
Encoding:
JavaScript  |  2011-03-08  |  27.1 KB  |  558 lines

  1. /*
  2.  *      Copyright (C) 2005-2010 Team XBMC
  3.  *      http://www.xbmc.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with XBMC; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21.  
  22. var MediaLibrary = function() {
  23.         this.init();
  24.         return true;
  25.     }
  26.  
  27. MediaLibrary.prototype = {
  28.         init: function() {
  29.             this.bindControls();
  30.         },
  31.         bindControls: function() {
  32.             $('#musicLibrary').click(jQuery.proxy(this.musicLibraryOpen, this));
  33.             $('#movieLibrary').click(jQuery.proxy(this.movieLibraryOpen, this));
  34.             $('#tvshowLibrary').click(jQuery.proxy(this.tvshowLibraryOpen, this));
  35.             $('#pictureLibrary').click(jQuery.proxy(this.pictureLibraryOpen, this));
  36.             $('#overlay').click(jQuery.proxy(this.hideOverlay, this));
  37.             $(window).resize(jQuery.proxy(this.updatePlayButtonLocation, this));
  38.         },
  39.         resetPage: function() {
  40.             $('#musicLibrary').removeClass('selected');
  41.             $('#movieLibrary').removeClass('selected');
  42.             $('#tvshowLibrary').removeClass('selected');
  43.             $('#pictureLibrary').removeClass('selected');
  44.             this.hideOverlay();
  45.         },
  46.         musicLibraryOpen: function(event) {
  47.             this.resetPage();
  48.             $('#musicLibrary').addClass('selected');
  49.             $('.contentContainer').hide();
  50.             var libraryContainer = $('#libraryContainer');
  51.             if (!libraryContainer || libraryContainer.length == 0) {
  52.                 $('#spinner').show();
  53.                 libraryContainer = $('<div>');
  54.                 libraryContainer.attr('id', 'libraryContainer')
  55.                                 .addClass('contentContainer');
  56.                 $('#content').append(libraryContainer);
  57.                 jQuery.post(JSON_RPC + '?GetAlbums', '{"jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "start": 0, "fields": ["album_description", "album_theme", "album_mood", "album_style", "album_type", "album_label", "album_artist", "album_genre", "album_rating", "album_title"] }, "id": 1}', jQuery.proxy(function(data) {
  58.                     if (data && data.result && data.result.albums) {
  59.                         this.albumList = data.result.albums;
  60.                         this.albumList.sort(jQuery.proxy(this.albumArtistSorter, this));
  61.                         $.each($(this.albumList), jQuery.proxy(function(i, item) {
  62.                             var floatableAlbum = this.generateThumb('album', item.thumbnail, item.album_title, item.album_artist);
  63.                             floatableAlbum.bind('click', { album: item }, jQuery.proxy(this.displayAlbumDetails, this));
  64.                             libraryContainer.append(floatableAlbum);
  65.                         }, this));
  66.                         libraryContainer.append($('<div>').addClass('footerPadding'));
  67.                         $('#spinner').hide();
  68.                         //$('#libraryContainer img').lazyload();
  69.                         libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
  70.                         libraryContainer.trigger('scroll');
  71.                         myScroll = new iScroll('libraryContainer');
  72.                     } else {
  73.                         libraryContainer.html('');
  74.                     }
  75.                 }, this), 'json');
  76.             } else {
  77.                 libraryContainer.show();
  78.                 libraryContainer.trigger('scroll');
  79.             }
  80.         },
  81.         getThumbnailPath: function(thumbnail) {
  82.             return thumbnail ? ('/vfs/' + thumbnail) : DEFAULT_ALBUM_COVER;
  83.         },
  84.         generateThumb: function(type, thumbnail, album_title, album_artist) {
  85.             var floatableAlbum = $('<div>');
  86.             var path = this.getThumbnailPath(thumbnail);
  87.             var title = album_title||'';
  88.             var artist = album_artist||'';
  89.             if (title.length > 18 && !(title.length <= 21)) {
  90.                 title = album_title.substring(0, 18) + '...';
  91.             }
  92.             if (artist.length > 20 && !(artist.length <= 22)) {
  93.                 artist = album_artist.substring(0, 20) + '...';
  94.             }
  95.             var className = '';
  96.             var code = '';
  97.             switch(type) {
  98.                 case 'album':
  99.                     className = 'floatableAlbum';
  100.                     code = '<p class="album" title="' + album_title + '">' + title + '</p><p class="artist" title="' + album_artist + '">' + artist + '</p>';
  101.                     break;
  102.                 case 'movie':
  103.                     className = 'floatableMovieCover';
  104.                     code = '<p class="album" title="' + album_title + '">' + title + '</p>';
  105.                     break;
  106.                 case 'tvshow':
  107.                     className = 'floatableTVShowCover';
  108.                     break;
  109.                 case 'image':
  110.                 case 'directory':
  111.                     className = 'floatableAlbum';
  112.                     code = '<p class="album" title="' + album_title + '">' + title + '</p>';
  113.                     break;
  114.             }
  115.             return floatableAlbum.addClass(className).html('<div class="imgWrapper"><div class="inner"><img src="' + path + '" alt="" /></div></div>' + code);
  116.         },
  117.         showAlbumSelectorBlock: function(album) {
  118.             if (album) {
  119.                 //Find album in stored array
  120.                 var prevAlbum = null,
  121.                     nextAlbum = null;
  122.                 $.each($(this.albumList), jQuery.proxy(function(i, item) {
  123.                     if (item.albumid == album.albumid) {
  124.                         if (this.albumList.length > 1) {
  125.                             prevAlbum = this.albumList[i <= 0 ? this.albumList.length-1 : i-1];
  126.                             nextAlbum = this.albumList[i >= this.albumList.length ? 0 : i+1];
  127.                         }
  128.                         return false; /* .each break */
  129.                     }
  130.                 }, this));
  131.                 var albumSelectorBlock = $('#albumSelector');
  132.                 if (!albumSelectorBlock || albumSelectorBlock.length == 0) {
  133.                     albumSelectorBlock = $('<div>');
  134.                     albumSelectorBlock.attr('id', 'albumSelector')
  135.                                       .html('<table><tr><td class="allAlbums">All Albums</td><td class="activeAlbumTitle"></td><td class="prevAlbum"> </td><td class="nextAlbum"> </td></tr></table>');
  136.                     $('#content').prepend(albumSelectorBlock);
  137.                     $('#albumSelector .allAlbums').bind('click', jQuery.proxy(this.hideAlbumDetails, this));
  138.                 }
  139.                 $('#albumSelector .prevAlbum').unbind();
  140.                 $('#albumSelector .nextAlbum').unbind();
  141.                 if (prevAlbum) {
  142.                     $('#albumSelector .prevAlbum').bind('click', {album: prevAlbum}, jQuery.proxy(this.displayAlbumDetails, this));
  143.                 }
  144.                 if (nextAlbum) {
  145.                     $('#albumSelector .nextAlbum').bind('click', {album: nextAlbum}, jQuery.proxy(this.displayAlbumDetails, this));
  146.                 }
  147.                 $('#albumSelector .activeAlbumTitle').html(album.album_title||'Unknown Album');
  148.                 albumSelectorBlock.show();
  149.             }
  150.         },
  151.         hideAlbumDetails: function() {
  152.             $('.contentContainer').hide();
  153.             this.musicLibraryOpen();
  154.         },
  155.         displayAlbumDetails: function(event) {
  156.             this.showAlbumSelectorBlock(event.data.album);
  157.             var albumDetailsContainer = $('#albumDetails' + event.data.album.albumid);
  158.             $('#topScrollFade').hide();
  159.             if (!albumDetailsContainer || albumDetailsContainer.length == 0) {
  160.                 $('#spinner').show();
  161.                 jQuery.post(JSON_RPC + '?GetSongs', '{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": { "fields": ["title", "artist", "genre", "tracknumber", "discnumber", "duration", "year"], "albumid" : ' + event.data.album.albumid + ' }, "id": 1}', jQuery.proxy(function(data) {
  162.                     albumDetailsContainer = $('<div>');
  163.                     albumDetailsContainer.attr('id', 'albumDetails' + event.data.album.albumid)
  164.                                          .addClass('contentContainer')
  165.                                          .addClass('albumContainer')
  166.                                          .html('<table class="albumView"><thead><tr class="headerRow"><th>Artwork</th><th> </th><th>Name</th><th class="time">Time</th><th>Artist</th><th>Genre</th></tr></thead><tbody class="resultSet"></tbody></table>');
  167.                     $('.contentContainer').hide();
  168.                     $('#content').append(albumDetailsContainer);
  169.                     var albumThumbnail = event.data.album.thumbnail;
  170.                     var albumTitle = event.data.album.album_title||'Unknown Album';
  171.                     var albumArtist = event.data.album.album_artist||'Unknown Artist';
  172.                     var trackCount = data.result.total;
  173.                     $.each($(data.result.songs), jQuery.proxy(function(i, item) {
  174.                         if (i == 0) {
  175.                             var trackRow = $('<tr>').addClass('trackRow').addClass('tr' + i % 2);
  176.                             trackRow.append($('<td>').attr('rowspan', ++trackCount + 1).addClass('albumThumb'));
  177.                             for (var a = 0; a < 5; a++) {
  178.                                 trackRow.append($('<td>').html(' ').attr('style', 'display: none'));
  179.                             }
  180.                             $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
  181.                         }
  182.                         var trackRow = $('<tr>').addClass('trackRow').addClass('tr' + i % 2);
  183.                         var trackNumberTD = $('<td>')
  184.                             .html(item.tracknumber)
  185.                             .bind('click', { song: item, album: event.data.album }, jQuery.proxy(this.playTrack, this));
  186.                         trackRow.append(trackNumberTD);
  187.                         var trackTitleTD = $('<td>')
  188.                             .html(item.title)
  189.                             .bind('click', { song: item, album: event.data.album }, jQuery.proxy(this.playTrack, this));
  190.                         trackRow.append(trackTitleTD);
  191.                         var trackDurationTD = $('<td>')
  192.                             .addClass('time')
  193.                             .html(durationToString(item.duration))
  194.                             .bind('click', { song: item, album: event.data.album }, jQuery.proxy(this.playTrack, this));
  195.                         trackRow.append(trackDurationTD);
  196.                         var trackArtistTD = $('<td>')
  197.                             .html(item.artist)
  198.                             .bind('click', { song: item, album: event.data.album }, jQuery.proxy(this.playTrack, this));
  199.                         trackRow.append(trackArtistTD);
  200.                         var trackGenreTD = $('<td>')
  201.                             .html(item.genre)
  202.                             .bind('click', { song: item, album: event.data.album }, jQuery.proxy(this.playTrack, this));
  203.                         trackRow.append(trackGenreTD);
  204.                         $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
  205.                     }, this));
  206.                     if (trackCount > 0) {
  207.                         var trackRow = $('<tr>').addClass('fillerTrackRow');
  208.                         for (var i = 0; i < 5; i++) {
  209.                             trackRow.append($('<td>').html(' '));
  210.                         }
  211.                         $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
  212.  
  213.                         var trackRow2 = $('<tr>').addClass('fillerTrackRow2');
  214.                         trackRow2.append($('<td>').addClass('albumBG').html(' '));
  215.                         for (var i = 0; i < 5; i++) {
  216.                             trackRow2.append($('<td>').html(' '));
  217.                         }
  218.                         $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow2);
  219.                     }
  220.                     $('#albumDetails' + event.data.album.albumid + ' .albumThumb')
  221.                         .append(this.generateThumb('album', albumThumbnail, albumTitle, albumArtist))
  222.                         .append($('<div>').addClass('footerPadding'));
  223.                     $('#spinner').hide();
  224.                     myScroll = new iScroll('albumDetails' + event.data.album.albumid);
  225.                 }, this), 'json');
  226.             } else {
  227.                 $('.contentContainer').hide();
  228.                 $('#albumDetails' + event.data.album.albumid).show();
  229.             }
  230.         },
  231.         displayTVShowDetails: function(event) {
  232.             var tvshowDetailsContainer = $('#tvShowDetails' + event.data.tvshow.tvshowid);
  233.             $('#topScrollFade').hide();
  234.             if (!tvshowDetailsContainer || tvshowDetailsContainer.length == 0) {
  235.                 $('#spinner').show();
  236.                 jQuery.post(JSON_RPC + '?GetTVShowSeasons', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetSeasons", "params": { "fields": ["genre", "director", "trailer", "tagline", "plot", "plotoutline", "title", "originaltitle", "lastplayed", "showtitle", "firstaired", "duration", "season", "episode", "runtime", "year", "playcount", "rating", "writer", "studio", "mpaa", "premiered"], "tvshowid" : ' + event.data.tvshow.tvshowid + ' }, "id": 1}', jQuery.proxy(function(data) {
  237.                     tvshowDetailsContainer = $('<div>');
  238.                     tvshowDetailsContainer.attr('id', 'tvShowDetails' + event.data.tvshow.tvshowid)
  239.                                           .css('display', 'none')
  240.                                           .addClass('contentContainer')
  241.                                           .addClass('tvshowContainer');
  242.                     tvshowDetailsContainer.append(this.generateThumb('tvshow', event.data.tvshow.thumbnail, event.data.tvshow.title));
  243.                     if (data && data.result && data.result.seasons && data.result.seasons.length > 0) {
  244.                         var absWrapper = $('<div>').addClass('showDetailsWrapper');
  245.                         var showDetails = $('<div>').addClass('showDetails');
  246.                         showDetails.append($('<p>').html(data.result.seasons[0].showtitle).addClass('showTitle'));
  247.                         showDetails.append($('<p>').html('<span class="heading">Genre:</span> ' + data.result.seasons[0].genre));
  248.                         showDetails.append($('<p>').html('<span class="heading">Studio:</span> ' + data.result.seasons[0].studio));
  249.                         absWrapper.append(showDetails);
  250.                         var seasonSelectionContainer = $('<div>').addClass('seasonPicker');
  251.                         var seasonSelectionList = $('<ul>');
  252.                         var episodeCount = 0;
  253.                         var firstSeason;
  254.                         $.each($(data.result.seasons), jQuery.proxy(function(i, item) {
  255.                             episodeCount += item.episode;
  256.                             var season = $('<li>').html(item.title);
  257.                             if (i == 0) {
  258.                                 season.addClass('activeSeason');
  259.                                 firstSeason = season;
  260.                                 this.tvActiveShowContainer = tvshowDetailsContainer;
  261.                             }
  262.                             season.bind('click', {tvshow: event.data.tvshow.tvshowid, season: item, element: season}, jQuery.proxy(this.displaySeasonListings, this));
  263.                             seasonSelectionList.append(season);
  264.                         }, this));
  265.                         showDetails.append($('<p>').html('<span class="heading">Episodes:</span> ' + episodeCount));
  266.                         seasonSelectionContainer.append(seasonSelectionList);
  267.                         absWrapper.append(seasonSelectionContainer);
  268.                         tvshowDetailsContainer.append(absWrapper);
  269.                         if (firstSeason) {
  270.                             firstSeason.trigger('click');
  271.                         }
  272.                         $('#content').append(tvshowDetailsContainer);
  273.                         tvshowDetailsContainer.fadeIn();
  274.                     }
  275.                     $('#spinner').hide();
  276.                 }, this), 'json');
  277.             } else {
  278.                 $('.contentContainer').hide();
  279.                 $('#tvShowDetails' + event.data.show.showid);
  280.             }
  281.         },
  282.         displaySeasonListings: function(event) {
  283.             if (event.data.element != this.tvActiveSeason) {
  284.                 //Remove style from old season.
  285.                 if (this.tvActiveSeason) {
  286.                     $(this.tvActiveSeason).removeClass('activeSeason');
  287.                 }
  288.                 //Hide old listings
  289.                 var oldListings = $('.episodeListingsContainer', this.tvActiveShowContainer).fadeOut();
  290.                 //Update ActiveSeason
  291.                 this.tvActiveSeason = event.data.element;
  292.                 $(this.tvActiveSeason).addClass('activeSeason');            
  293.                 //Populate new listings
  294.                 jQuery.post(JSON_RPC + '?GetTVSeasonEpisodes', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "fields": ["genre", "director", "trailer", "tagline", "plot", "plotoutline", "title", "originaltitle", "lastplayed", "showtitle", "firstaired", "duration", "season", "episode", "runtime", "year", "playcount", "rating", "writer", "studio", "mpaa", "premiered"], "season" : ' + event.data.season.season + ', "tvshowid" : ' + event.data.tvshow + ' }, "id": 1}', jQuery.proxy(function(data) {
  295.                     var episodeListingsContainer = $('<div>').addClass('episodeListingsContainer');
  296.                     var list = $('<ul>');
  297.                     $.each($(data.result.episodes), jQuery.proxy(function(i, item) {
  298.                         var episodePicture = $('<img>');
  299.                         episodePicture.attr('src', this.getThumbnailPath(item.thumbnail));
  300.                         var episodeTitle = $('<p>').html(item.title);
  301.                         var episode = $('<li>').append(episodePicture).append(episodeTitle);
  302.                         list.append(episode);
  303.                     }, this));
  304.                     episodeListingsContainer.append(list);
  305.                     $(this.tvActiveShowContainer).prepend(episodeListingsContainer);
  306.                 }, this), 'json');
  307.             }
  308.         },
  309.         hideOverlay: function(event) {
  310.             if (this.activeCover) {
  311.                 $(this.activeCover).remove();
  312.                 this.activeCover = null;
  313.             }
  314.             $('#overlay').hide();
  315.         },
  316.         updatePlayButtonLocation: function(event) {
  317.             var movieContainer = $('.movieCover');
  318.             if (movieContainer.length > 0) {
  319.                 var playIcon = $('.playIcon');
  320.                 if (playIcon.length > 0) {
  321.                     playIcon.width($(movieContainer[0]).width());
  322.                     playIcon.height($(movieContainer[0]).height());
  323.                 }
  324.             }
  325.         },
  326.         playMovie: function(event) {
  327.             jQuery.post(JSON_RPC + '?PlayMovie', '{"jsonrpc": "2.0", "method": "XBMC.Play", "params": { "movieid": ' + event.data.movie.movieid + ' }, "id": 1}', jQuery.proxy(function(data) {
  328.                 this.hideOverlay();
  329.             }, this), 'json');
  330.         },
  331.         displayMovieDetails: function(event) {
  332.             var movieDetails = $('<div>').attr('id', 'movie-' + event.data.movie.movieid).addClass('moviePopoverContainer');
  333.             movieDetails.append($('<img>').attr('src', '/images/close-button.png').addClass('closeButton').bind('click', jQuery.proxy(this.hideOverlay, this)));
  334.             movieDetails.append($('<img>').attr('src', this.getThumbnailPath(event.data.movie.thumbnail)).addClass('movieCover'));
  335.             movieDetails.append($('<div>').addClass('playIcon').bind('click', {movie: event.data.movie}, jQuery.proxy(this.playMovie, this)));
  336.             var movieTitle = $('<p>').addClass('movieTitle');
  337.             var yearText = event.data.movie.year ? ' <span class="year">(' + event.data.movie.year + ')</span>' : '';
  338.             movieTitle.html(event.data.movie.title + yearText);
  339.             movieDetails.append(movieTitle);
  340.             if (event.data.movie.runtime) {
  341.                 movieDetails.append($('<p>').addClass('runtime').html('<strong>Runtime:</strong> ' + event.data.movie.runtime + ' minutes'));
  342.             }
  343.             if (event.data.movie.plot) {
  344.                 movieDetails.append($('<p>').addClass('plot').html(event.data.movie.plot));
  345.             }
  346.             if (event.data.movie.genre) {
  347.                 movieDetails.append($('<p>').addClass('genre').html('<strong>Genre:</strong> ' + event.data.movie.genre));
  348.             }
  349.             if (event.data.movie.rating) {
  350.                 //Todo
  351.             }
  352.             if (event.data.movie.director) {
  353.                 movieDetails.append($('<p>').addClass('director').html('<strong>Directed By:</strong> ' + event.data.movie.director));
  354.             }
  355.             this.activeCover = movieDetails;
  356.             $('body').append(movieDetails);
  357.             $('#overlay').show();
  358.             this.updatePlayButtonLocation();
  359.         },
  360.         playTrack: function(event) {
  361.             jQuery.post(JSON_RPC + '?ClearPlaylist', '{"jsonrpc": "2.0", "method": "AudioPlaylist.Clear", "id": 1}', jQuery.proxy(function(data) {
  362.                 //check that clear worked.
  363.                 jQuery.post(JSON_RPC + '?AddAlbumToPlaylist', '{"jsonrpc": "2.0", "method": "AudioPlaylist.Add", "params": { "albumid": ' + event.data.album.albumid + ' }, "id": 1}', jQuery.proxy(function(data) {
  364.                     //play specific song in playlist
  365.                     jQuery.post(JSON_RPC + '?PlaylistItemPlay', '{"jsonrpc": "2.0", "method": "AudioPlaylist.Play", "params": { "songid": ' + event.data.song.songid + ' }, "id": 1}', function() {}, 'json');
  366.                 }, this), 'json');
  367.             }, this), 'json');
  368.         },
  369.         movieLibraryOpen: function() {
  370.             this.resetPage();
  371.             $('#movieLibrary').addClass('selected');
  372.             $('.contentContainer').hide();
  373.             var libraryContainer = $('#movieLibraryContainer');
  374.             if (!libraryContainer || libraryContainer.length == 0) {
  375.                 $('#spinner').show();
  376.                 jQuery.post(JSON_RPC + '?GetMovies', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "start": 0, "fields": ["genre", "director", "trailer", "tagline", "plot", "plotoutline", "title", "originaltitle", "lastplayed", "showtitle", "firstaired", "duration", "season", "episode", "runtime", "year", "playcount", "rating"] }, "id": 1}', jQuery.proxy(function(data) {
  377.                     if (data && data.result && data.result.movies) {
  378.                             libraryContainer = $('<div>');
  379.                             libraryContainer.attr('id', 'movieLibraryContainer')
  380.                                             .addClass('contentContainer');
  381.                             $('#content').append(libraryContainer);
  382.                     } else {
  383.                         libraryContainer.html('');
  384.                     }
  385.                     data.result.movies.sort(jQuery.proxy(this.movieTitleSorter, this));
  386.                     $.each($(data.result.movies), jQuery.proxy(function(i, item) {
  387.                         var floatableMovieCover = this.generateThumb('movie', item.thumbnail, item.title);
  388.                         floatableMovieCover.bind('click', { movie: item }, jQuery.proxy(this.displayMovieDetails, this));
  389.                         libraryContainer.append(floatableMovieCover);
  390.                     }, this));
  391.                     libraryContainer.append($('<div>').addClass('footerPadding'));
  392.                     $('#spinner').hide();
  393.                     libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
  394.                     libraryContainer.trigger('scroll');
  395.                     //$('#libraryContainer img').lazyload();
  396.                     myScroll = new iScroll('movieLibraryContainer');
  397.                 }, this), 'json');
  398.             } else {
  399.                 libraryContainer.show();
  400.                 libraryContainer.trigger('scroll');
  401.             }
  402.         },
  403.         tvshowLibraryOpen: function() {
  404.             this.resetPage();
  405.             $('#tvshowLibrary').addClass('selected');
  406.             $('.contentContainer').hide();
  407.             var libraryContainer = $('#tvshowLibraryContainer');
  408.             if (!libraryContainer || libraryContainer.length == 0) {
  409.                 $('#spinner').show();
  410.                 jQuery.post(JSON_RPC + '?GetTVShows', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "start": 0, "fields": ["genre", "director", "trailer", "tagline", "plot", "plotoutline", "title", "originaltitle", "lastplayed", "showtitle", "firstaired", "duration", "season", "episode", "runtime", "year", "playcount", "rating"] }, "id": 1}', jQuery.proxy(function(data) {
  411.                     if (data && data.result && data.result.tvshows) {
  412.                             libraryContainer = $('<div>');
  413.                             libraryContainer.attr('id', 'tvshowLibraryContainer')
  414.                                             .addClass('contentContainer');
  415.                             $('#content').append(libraryContainer);
  416.                     } else {
  417.                         libraryContainer.html('');
  418.                     }
  419.                     $.each($(data.result.tvshows), jQuery.proxy(function(i, item) {
  420.                         var floatableTVShowCover = this.generateThumb('tvshow', item.thumbnail, item.title);
  421.                         floatableTVShowCover.bind('click', { tvshow: item }, jQuery.proxy(this.displayTVShowDetails, this));
  422.                         libraryContainer.append(floatableTVShowCover);
  423.                     }, this));
  424.                     libraryContainer.append($('<div>').addClass('footerPadding'));
  425.                     //$('#libraryContainer img').lazyload();
  426.                     $('#spinner').hide();
  427.                     libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
  428.                     libraryContainer.trigger('scroll');
  429.                     myScroll = new iScroll('tvshowLibraryContainer');
  430.                 }, this), 'json');
  431.             } else {
  432.                 libraryContainer.show();
  433.                 libraryContainer.trigger('scroll');
  434.             }
  435.         },
  436.         updateScrollEffects: function(event) {
  437.             if (event.data.activeLibrary && $(event.data.activeLibrary).scrollTop() > 0) {
  438.                 $('#topScrollFade').fadeIn();
  439.             } else {
  440.                 $('#topScrollFade').fadeOut();
  441.             }
  442.         },
  443.         albumArtistSorter: function(a, b) {
  444.             var result = this.sortAlpha(a.album_artist, b.album_artist);
  445.             if (result == 0) {
  446.                 return this.sortAlpha(a.album_title, b.album_title);
  447.             }
  448.             return result;
  449.         },
  450.         sortAlpha: function(aStr, bStr) {
  451.             aStr = aStr.toLowerCase();
  452.             bStr = bStr.toLowerCase();
  453.             if (aStr < bStr) {
  454.                 return -1;
  455.             }
  456.             if (aStr > bStr) {
  457.                 return 1;
  458.             }
  459.             return 0;
  460.         },
  461.         movieTitleSorter: function(a, b) {
  462.             return this.sortAlpha(a.title, b.title);
  463.         },
  464.         startSlideshow: function(event) {
  465.             var directory = event.data.directory.file;
  466.             jQuery.post(JSON_RPC + '?StartSlideshow', '{"jsonrpc": "2.0", "method": "XBMC.StartSlideshow", "params": { "recursive" : "true", "random":"true", "directory" : "' + directory + '" }, "id": 1}', null, 'json');
  467.         },
  468.         showDirectory: function(event) {
  469.             var directory = event.data.directory.file;
  470.             this.resetPage();
  471.             $('#pictureLibrary').addClass('selected');
  472.             $('.contentContainer').hide();
  473.             var libraryContainer = $('#pictureLibraryDirContainer' + directory);
  474.             if (!libraryContainer || libraryContainer.length == 0) {
  475.                 $('#spinner').show();                           
  476.                 jQuery.post(JSON_RPC + '?GetDirectory', '{"jsonrpc": "2.0", "method": "Files.GetDirectory", "params": { "media" : "pictures", "directory":"' + directory + '" }, "id": 1}', jQuery.proxy(function(data) {
  477.                     if (data && data.result && ( data.result.directories || data.result.files )) {
  478.                         libraryContainer = $('<div>');
  479.                         libraryContainer.attr('id', 'pictureLibraryDirContainer' + directory)
  480.                                         .addClass('contentContainer');
  481.                         $('#content').append(libraryContainer);
  482.                         var breadcrumb = $('<div>');
  483.                         var seperator = '/';
  484.                         var item = '';
  485.                         var directoryArray = directory.split(seperator);
  486.                         jQuery.each(directoryArray, function(i,v) {
  487.                             if(v != '') {
  488.                                 item += v + seperator;
  489.                                 //tmp.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));               
  490.                                 breadcrumb.append($('<div>').text(' > ' + v).css('float','left').addClass('breadcrumb'));                                                 
  491.                             }
  492.                         });
  493.                         libraryContainer.append(breadcrumb);
  494.                         libraryContainer.append($('<div>').css('clear','both'));
  495.                         if (data.result.directories) {
  496.                             $.each($(data.result.directories), jQuery.proxy(function(i, item) {
  497.                                 var floatableShare = this.generateThumb('directory', item.thumbnail, item.label);
  498.                                 floatableShare.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));              
  499.                                 //var slideshow = $('<div">');
  500.                                 //slideshow.html('<div>Slideshow</div>');
  501.                                 //slideshow.bind('click', { directory: item }, jQuery.proxy(this.startSlideshow, this));        
  502.                                 //floatableShare.append(slideshow);
  503.                                 libraryContainer.append(floatableShare);
  504.                             }, this));
  505.                         }
  506.                         if (data.result.files) {
  507.                             $.each($(data.result.files), jQuery.proxy(function(i, item) {
  508.                                 var floatableImage = this.generateThumb('image', item.file, item.label);
  509.                                 libraryContainer.append(floatableImage);
  510.                             }, this));
  511.                         }
  512.                         libraryContainer.append($('<div>').addClass('footerPadding'));
  513.                     } else {
  514.                         libraryContainer.html('');
  515.                     }
  516.                     $('#spinner').hide();
  517.                     libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
  518.                     libraryContainer.trigger('scroll');
  519.                     myScroll = new iScroll('#pictureLibraryDirContainer' + directory);
  520.                 }, this), 'json');
  521.             } else {
  522.                 libraryContainer.show();
  523.                 libraryContainer.trigger('scroll');
  524.             }
  525.         },
  526.         pictureLibraryOpen: function() {
  527.             this.resetPage();
  528.             $('#pictureLibrary').addClass('selected');
  529.             $('.contentContainer').hide();
  530.             var libraryContainer = $('#pictureLibraryContainer');
  531.             if (!libraryContainer || libraryContainer.length == 0) {
  532.                 $('#spinner').show();
  533.                 jQuery.post(JSON_RPC + '?GetSources', '{"jsonrpc": "2.0", "method": "Files.GetSources", "params": { "media" : "pictures" }, "id": 1}',                                  jQuery.proxy(function(data) {
  534.                     if (data && data.result && data.result.shares) {
  535.                         libraryContainer = $('<div>');
  536.                         libraryContainer.attr('id', 'pictureLibraryContainer')
  537.                                         .addClass('contentContainer');
  538.                         $('#content').append(libraryContainer);
  539.                     } else {
  540.                         libraryContainer.html('');
  541.                     }
  542.                     $.each($(data.result.shares), jQuery.proxy(function(i, item) {
  543.                         var floatableShare = this.generateThumb('directory', item.thumbnail, item.label);
  544.                         floatableShare.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));                                      
  545.                         libraryContainer.append(floatableShare);
  546.                     }, this));
  547.                     libraryContainer.append($('<div>').addClass('footerPadding'));
  548.                     $('#spinner').hide();
  549.                     libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
  550.                     libraryContainer.trigger('scroll');
  551.                     myScroll = new iScroll('#pictureLibraryContainer');
  552.                 }, this), 'json');
  553.             } else {
  554.                 libraryContainer.show();
  555.                 libraryContainer.trigger('scroll');
  556.             }
  557.         }
  558.     }